package  com.TCPServer
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	/**
	 * ...
	 * @author Omar Contreras
	 */
	public class TCPServerSocket extends EventDispatcher
	{
		public static const GET_DATA:int = 1;
		
		public static const SEND_STRING:int = 0;
		public static const SEND_INT:int = 1;
		public static const SEND_FLOAT:int = 2;
		public static const SEND_BYTEARRAY:int = 3;
		
		private var _first_byte:Number;
		private var _second_byte:Number;
		private var _packet_size:Number;
		private var _socket:Socket;
		private var _buffer:ByteArray;
		private var _port:Number;
		private var _data_obj:Object;
		private var totalBytes:Number = 0;
		
		public function TCPServerSocket(host:String = 'localhost', port:int = 1007):void 
		{
			_buffer = new ByteArray();
			_socket = new Socket();
			_data_obj = new Object();
			
			_socket.addEventListener(Event.CONNECT, onConnect);
			_socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
			_socket.addEventListener(IOErrorEvent.IO_ERROR, onSocketError);
			
			_port = port;
			_packet_size = 0;
			if (!_socket.connected) 
				_socket.connect(host, port);
			else
				dispatchEvent(new TCPServerSocketEvent(TCPServerSocketEvent.ONCONNECT, null));
			
		}
		
		public function sendCommand(type:int, data:*):int
		{
			if (data.length > 0)
			{
				switch (type) 
				{
					case SEND_STRING:
						_socket.writeUTFBytes(String(data));
					break;
					
					case SEND_INT:
						_socket.writeInt(int(data));
					break;
					
					case SEND_FLOAT:
						_socket.writeFloat(Number(data));
					break;
					
					case SEND_BYTEARRAY:
						
					break;
				default:
					_socket.writeUTFBytes(String(data));
				}
				//_socket.writeBytes(data, 0, data.length);
				//trace("Data Lenght: " + data.length);
				//_socket.writeInt(3);
				_socket.flush();
				return TCPServerSocketEvent.S_OK;
			} 
			else 
			{
				return TCPServerSocketEvent.S_ERROR;
			}
		}
		
		private function onSocketError(e:IOErrorEvent):void 
		{
			trace("Error! :" + e.toString());
		}
		
		private function onSocketData(e:ProgressEvent):void 
		{
			//trace("Data Arriving!");
			_buffer.clear();
			
			if (_socket.bytesAvailable > 0) 
			{
				if(_packet_size <= 0) {
					_socket.endian = Endian.LITTLE_ENDIAN;
					_first_byte = int(_socket.readByte());
					_second_byte = int(_socket.readByte());
					_packet_size = int(_socket.readInt());
					//trace("First: " + _first_byte + " - Second: " + _second_byte + " - Size: " + _packet_size + "- Available: " + _socket.bytesAvailable);
				}
				if (_socket.bytesAvailable >= _packet_size && _packet_size > 0)
				{
					_socket.readBytes(_buffer, 0, _packet_size);
					_buffer.position = 0;
					_buffer.endian = Endian.LITTLE_ENDIAN;
					_data_obj.first = _first_byte;
					_data_obj.second = _second_byte;
					_data_obj.buffer = _buffer;
					_packet_size = 0;
					
					dispatchEvent(new TCPServerSocketEvent(TCPServerSocketEvent.ONDATA, _data_obj)); 
				}
			}
		}
		
		private function onConnect(e:Event):void 
		{
			trace("connected!");
			dispatchEvent(new TCPServerSocketEvent(TCPServerSocketEvent.ONCONNECT, null));
		}
		
	}

}